package local.michel.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifDirectory;
import com.google.common.io.Files;

/**
 * @author max
 * 
 */

public class Sorter {

	UserComparePics gui;
	
	ConcurrentLinkedQueue<PicAction> resultQueue;
	
	/**
	 * @param args
	 */
	File baseDir = null;

	private boolean stop = false;
	static Logger logger = Logger.getLogger(Sorter.class);

	public Sorter() {
		resultQueue = new ConcurrentLinkedQueue<PicAction>();
	}
	
	public void registerGui(Object gui) {
		this.gui = (UserComparePics) gui;
	}

	private void showPicturesToUserIfSame(File source, File destination) {
		logger.debug("source: " + source.getAbsolutePath()); 
		logger.debug("destination: " + destination.getAbsolutePath());

		gui.addAction(new PicAction(source, destination));
	}

	private void createDirectory(File destination) {
		destination.mkdir();
	}

	private void renameAndMoveMediaFile(File f, File destination) {
		// TODO Auto-generated method stub
		logger.debug("rename");
	}

	private void deleteFile(File f) {
		// TODO Auto-generated method stub
		logger.debug("delete");
	}

	private boolean mediaFilesAreEqual(File original, File destination) {
		File destinationFile = new File(destination, original.getName());
		boolean same = false;
		try {
			same = Files.getChecksum(destinationFile, new java.util.zip.CRC32()) == Files.getChecksum(original, new java.util.zip.CRC32());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return same;
	}

	private void moveMediaFile(File destination, File f) {
		logger.debug(String.format("would move file %s to directoy %s", f, destination));
	}

	private boolean destinationIsAvailable(File destination, File f) {
		File destinationFile = new File(destination, f.getName());
		return !(destinationFile.exists());
	}

	private File getAppropriateDirectory(File f) {
		String DATE_FORMAT = "yyyyMMdd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		Date creationDate = getCreationDate(f);
		String dirName = sdf.format(creationDate);
		logger.debug(dirName);
		return new File(baseDir, dirName);
	}

	private Date getCreationDate(File f) {
		Metadata metadata = null;
		try {
			metadata = JpegMetadataReader.readMetadata(f);
		} catch (JpegProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Date creationDate = null;
		try {
			creationDate = metadata.getDirectory(ExifDirectory.class).getDate(
					ExifDirectory.TAG_DATETIME);
			logger.debug(creationDate);
		} catch (MetadataException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return creationDate;
	}

	private List<File> findMediaFiles(File dirName) {
		return Arrays.asList(dirName.listFiles(new MediaFilter()));
	}

	private class MediaFilter implements FileFilter {
		String[] mediaExtensions = { "jpg", "jepg", "mov" };
		List<String> mediaExtensionsList = Arrays.asList(mediaExtensions);

		@Override
		public boolean accept(File file) {
			if (file.isFile()) {
				String fileName = file.getName();
				int sepIndex = fileName.lastIndexOf('.');
				String extension = fileName.substring(sepIndex + 1, fileName
						.length());
				extension = extension.toLowerCase();
				return mediaExtensionsList.contains(extension);
			}
			return false;
		}
	}


	public void start() {
		stop = false;
		String baseDirName = "C:/Users/max/Pictures/iPhone-Photos/";
		baseDir = new File(baseDirName);

		List<File> mediaFiles = findMediaFiles(baseDir);
		for (File f : mediaFiles) {
			if (stop) {
				break;
			}
			
			File destination = getAppropriateDirectory(f);
			if (!destination.exists()) {
				createDirectory(destination);
			}
			if (destinationIsAvailable(destination, f)) {
				moveMediaFile(destination, f);
			} else {
				logger.debug("compare");
				if (mediaFilesAreEqual(f, destination)) {
					System.out.println("del");
					deleteFile(f);
				} else {
					showPicturesToUserIfSame(f, new File(destination, f.getName()));
				}
			}

		}
		
		// TODO: check for user decision in resultQueue
		
	}

	public void stop() {
		// TODO Auto-generated method stub
		
		stop  = true;
	}

	public void addResult(PicAction result) {
		resultQueue.add(result);
	}


}
